package com.ruoyi.finance.service.impl;

import java.math.BigDecimal;
import java.util.List;

import com.ruoyi.caigou.api.RemoteBuyOrderService;
import com.ruoyi.caigou.domain.BuyOrder;
import com.ruoyi.common.core.constant.SecurityConstants;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.utils.DateUtils;
import com.ruoyi.common.core.web.domain.AjaxResult;
import com.ruoyi.common.security.utils.SecurityUtils;
import com.ruoyi.finance.domain.BuyMustPay;
import com.ruoyi.finance.domain.PayReconciliationDetail;
import com.ruoyi.finance.domain.Payment;
import com.ruoyi.finance.mapper.BuyMustPayMapper;
import com.ruoyi.finance.mapper.PayReconciliationDetailMapper;
import com.ruoyi.finance.mapper.PaymentMapper;
import com.ruoyi.system.api.RemoteStockInService;
import com.ruoyi.system.api.domain.store.StockIn;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.finance.mapper.PayReconciliationMapper;
import com.ruoyi.finance.domain.PayReconciliation;
import com.ruoyi.finance.service.IPayReconciliationService;
import org.springframework.transaction.annotation.Transactional;

/**
 * 应付核销单Service业务层处理
 *
 * @author lmj
 * @date 2024-11-14
 */
@Service
@Transactional
@Slf4j
public class PayReconciliationServiceImpl implements IPayReconciliationService {
    @Autowired
    private PayReconciliationMapper payReconciliationMapper;
    @Autowired
    private PayReconciliationDetailMapper payReconciliationDetailMapper;
    @Autowired
    private PaymentMapper paymentMapper;
    @Autowired
    private BuyMustPayMapper buyMustPayMapper;
    @Autowired
    private RemoteStockInService remoteStockInService;
    @Autowired
    private RemoteBuyOrderService remoteBuyOrderService;

    /**
     * 查询应付核销单
     *
     * @param id 应付核销单主键
     * @return 应付核销单
     */
    @Override
    public PayReconciliation selectPayReconciliationById(Integer id) {
        log.info("selectPayReconciliationById params:{}", id);
        PayReconciliation payReconciliation = payReconciliationMapper.selectPayReconciliationById(id);
        String code = payReconciliation.getDocumentCode();
        PayReconciliationDetail payReconciliationDetail = new PayReconciliationDetail();
        payReconciliationDetail.setReconciliationCode(code);
        //根据code获取详情
        List<PayReconciliationDetail> payReconciliationDetailList = payReconciliationDetailMapper.selectPayReconciliationDetailList(payReconciliationDetail);
        payReconciliation.setPayReconciliationDetailList(payReconciliationDetailList);
        return payReconciliation;
    }

    /**
     * 查询应付核销单列表
     *
     * @param payReconciliation 应付核销单
     * @return 应付核销单
     */
    @Override
    public List<PayReconciliation> selectPayReconciliationList(PayReconciliation payReconciliation) {
        return payReconciliationMapper.selectPayReconciliationList(payReconciliation);
    }

    /**
     * 新增应付核销单
     *
     * @param payReconciliation 应付核销单
     * @return 结果
     */
    @Override
    public AjaxResult insertPayReconciliation(PayReconciliation payReconciliation) {
        log.info("PayReconciliationServiceImpl insertPayReconciliation params:{}", payReconciliation);
        payReconciliation.setCreateTime(DateUtils.getNowDate());
        boolean flag = payReconciliationMapper.insertPayReconciliation(payReconciliation) > 0;
        if (!flag) {
            log.error("PayReconciliationServiceImpl insertPayReconciliation fail");
            throw new RuntimeException("插入应付核销单失败");
        }
        List<PayReconciliationDetail> payReconciliationDetailList = payReconciliation.getPayReconciliationDetailList();
        flag = payReconciliationDetailMapper.insertPayReconciliationDetails(payReconciliationDetailList) > 0;
        if (!flag) {
            log.error("PayReconciliationServiceImpl insertPayReconciliationDetails fail");
            throw new RuntimeException("插入应付核销单详情失败");
        }
        return AjaxResult.success();
    }

    /**
     * 修改应付核销单
     *
     * @param payReconciliation 应付核销单
     * @return 结果
     */
    @Override
    public AjaxResult updatePayReconciliation(PayReconciliation payReconciliation) {
        log.info("updatePayReconciliation params:{}", payReconciliation);
        boolean flag = payReconciliationMapper.updatePayReconciliation(payReconciliation) > 0;
        if (!flag) {
            log.error("updatePayReconciliation fail");
            throw new RuntimeException("更新核销单失败");
        }
        flag = payReconciliationDetailMapper.deletePayReconciliationDetailByCode(payReconciliation.getDocumentCode()) > 0;
        if (!flag) {
            log.error("deletePayReconciliationDetailByCode fail");
            throw new RuntimeException("删除核销单详情失败");
        }
        List<PayReconciliationDetail> payReconciliationDetailList = payReconciliation.getPayReconciliationDetailList();
        flag = payReconciliationDetailMapper.insertPayReconciliationDetails(payReconciliationDetailList) > 0;
        if (!flag) {
            log.error("insertPayReconciliationDetails fail");
            throw new RuntimeException("插入应付核销单详情失败");
        }
        return AjaxResult.success();
    }

    @Override
    public AjaxResult checkRecon(PayReconciliation payReconciliation) {
        log.info("checkRecon params:{}", payReconciliation);
        //修改核销单的状态
        payReconciliation.setApprovalResult(1);
        payReconciliation.setIsEffect(1);
        payReconciliation.setEffectiveTime(DateUtils.getNowDate());
        payReconciliation.setDocumentStage(1);
        payReconciliation.setApprover(SecurityUtils.getUsername());
        boolean flag = payReconciliationMapper.updatePayReconciliation(payReconciliation) > 0;
        if (!flag) {
            log.error("updatePayReconciliation fail");
            throw new RuntimeException("修改核销单失败");
        }
        //获取核销单的详细信息
        PayReconciliationDetail detail = new PayReconciliationDetail();
        detail.setReconciliationCode(payReconciliation.getDocumentCode());
        List<PayReconciliationDetail> payReconciliationDetailList = payReconciliationDetailMapper.selectPayReconciliationDetailList(detail);
        /*遍历详情，如果关联的是应付单，那么修改应付单的已核销金额
         * 获取应付单关联的入库单，修改入库单的已结算金额，判断入库单的类型，如果是采购入库单，
         * 那么获取采购入库单关联的采购订单，修改采购订单的已结算金额
         * 如果关联的是付款单，那么修改付款单的已结算金额*/
        for (PayReconciliationDetail payReconciliationDetail : payReconciliationDetailList) {
            if (payReconciliationDetail.getSourceDocumentType() == 1) {
                String code = payReconciliationDetail.getSourceDocumentNo();
                BuyMustPay buyMustPay = buyMustPayMapper.selectBuyMustPayByCode(code);
                //判断结算金额大小
                BigDecimal verifiedAmount = buyMustPay.getVerifiedAmount().add(payReconciliationDetail.getReconciliationAmount());
                if (verifiedAmount.compareTo(buyMustPay.getTotalAmount()) > 0) {
                    throw new RuntimeException("核销金额不能大于总金额");
                }
                buyMustPay.setVerifiedAmount(verifiedAmount);
                flag = buyMustPayMapper.updateBuyMustPay(buyMustPay) > 0;
                if (!flag) {
                    log.error("updateBuyMustPay fail");
                    throw new RuntimeException("修改应付单失败");
                }
                //获取入库单
                code = buyMustPay.getSourceCode();
                R<StockIn> result = remoteStockInService.getStockInByCode(code, SecurityConstants.INNER);
                StockIn stockIn = result.getData();
                //判断结算金额大小
                BigDecimal paidAmount = stockIn.getPaidAmount().add(payReconciliationDetail.getReconciliationAmount());
                if (paidAmount.compareTo(stockIn.getCost()) > 0) {
                    throw new RuntimeException("核销金额不能大于总金额");
                }
                stockIn.setPaidAmount(paidAmount);
                R<Boolean> result1 = remoteStockInService.innerUpd(stockIn, SecurityConstants.INNER);
                if (!result1.getData()) {
                    log.error("innerUpd fail");
                    throw new RuntimeException("修改入库单错误");
                }
                //获取采购订单
                if (stockIn.getInventoryType() == 1) {
                    code = stockIn.getOrderCode();
                    R<BuyOrder> result2 = remoteBuyOrderService.getInfoByCode(code, SecurityConstants.INNER);
                    BuyOrder buyOrder = result2.getData();
                    BigDecimal paidAmount2 = buyOrder.getPaidAmount().add(payReconciliationDetail.getReconciliationAmount());
                    int compareR = paidAmount2.compareTo(buyOrder.getTotalAmount());
                    if (compareR > 0) {
                        throw new RuntimeException("核销金额不能大于总金额");
                    }
                    if (compareR < 0) {
                        buyOrder.setPayStatus(1);
                    }
                    if (compareR == 0) {
                        buyOrder.setPayStatus(2);
                    }
                    buyOrder.setPaidAmount(paidAmount2);
                    R<Boolean> booleanR = remoteBuyOrderService.innerEdit(buyOrder, SecurityConstants.INNER);
                    if (!booleanR.getData()) {
                        log.error("innerEdit fail");
                        throw new RuntimeException("修改采购订单错误");
                    }
                }
            }
            if (payReconciliationDetail.getSourceDocumentType() == 2) {
                String code = payReconciliationDetail.getSourceDocumentNo();
                Payment payment = paymentMapper.selectPaymentByCode(code);
                BigDecimal verAmount = payment.getVerifiedAmount().add(payReconciliationDetail.getReconciliationAmount());
                if (verAmount.compareTo(payment.getTotalAmount())>0){
                    throw new RuntimeException("付款单核销金额不足");
                }
                payment.setVerifiedAmount(verAmount);
                flag = paymentMapper.updatePayment(payment) > 0;
                if (!flag) {
                    log.error("updatePayment fail");
                    throw new RuntimeException("修改付款单失败");
                }
            }
        }
        return AjaxResult.success();
    }

    /**
     * 批量删除应付核销单
     *
     * @param ids 需要删除的应付核销单主键
     * @return 结果
     */
    @Override
    public int deletePayReconciliationByIds(Integer[] ids) {
        return payReconciliationMapper.deletePayReconciliationByIds(ids);
    }

    /**
     * 删除应付核销单信息
     *
     * @param id 应付核销单主键
     * @return 结果
     */
    @Override
    public int deletePayReconciliationById(Integer id) {
        return payReconciliationMapper.deletePayReconciliationById(id);
    }
}
